package org.fxml.managers {
	import org.fxml.display.INavigation;

	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.Sprite;
	import flash.events.Event;

	/**
	 * @author jordandoczy
	 */
	public class Navigation extends Sprite implements INavigation {
		
		protected var _activeEvent:String;
		protected var _activeIndex:int;
		protected var _container : DisplayObjectContainer;
		protected var _items:Array = new Array();
		protected var _length : int;
		protected var _navigationItemClass : Class;
		protected var _nonActiveEvent:String;
		protected var _selectedEvent:String;
		protected var _selectedIndex : int = -1;

		public function Navigation(){
			addEventListener(Event.ADDED_TO_STAGE, onAddedToStage, false, 0, true);
		}
		
		public function get activeEvent():String{
			return _activeEvent;		
		}
		
		public function set activeEvent(value:String):void{
			_activeEvent = value;
		}
		
		public function get activeIndex():int{
			return _activeIndex;
		}
		
		public function set activeIndex(value:int):void{
			_activeIndex = value;
		}
		
		public function get container():DisplayObjectContainer{
			return _container;
		}
		
		public function set container(value:DisplayObjectContainer):void{
			_container = value;	
			super.addChild(value);
		}
		
		public function get navigationItemClass():Class{
			return _navigationItemClass;
		}
		
		public function set navigationItemClass(value:Class):void{
			_navigationItemClass = value;
		}
		
		public function get nonActiveEvent():String{
			return _nonActiveEvent;		
		}
		
		public function set nonActiveEvent(value:String):void{
			_nonActiveEvent = value;
		}
		
		public function get length():int{
			return _length;
		}
		
		public function set length(value:int):void{
			_length = value; 
		}
		
		public function get selectedEvent():String{
			return _selectedEvent;		
		}
		
		public function set selectedEvent(value:String):void{
			_selectedEvent = value;
		}

		[Bindable]
		public function get selectedIndex():int{
			return _selectedIndex;
		}
		
		public function set selectedIndex(value:int):void{
			if(value == _selectedIndex) return;
			
			var selected:String = "selected";
			
			if(selectedItem && selectedItem.hasOwnProperty(selected)) selectedItem[selected] = false;	
			_selectedIndex = value;
			if(selectedItem && selectedItem.hasOwnProperty(selected)) selectedItem[selected] = true;
			dispatchEvent(new Event(Event.CHANGE));
		}
		
		protected function get selectedItem():DisplayObject{
			if(selectedIndex < 0) return null;
			else return _items[selectedIndex] || null;
		}
		
		public override function addChild(child:DisplayObject):DisplayObject{
			_items.push(child);
			
			if(_container) return _container.addChild(child);
			else return super.addChild(child);
		}
			
		public override function getChildIndex(child:DisplayObject):int{
			if(_container) return _container.getChildIndex(child);
			else return super.getChildIndex(child);
		}
			
		protected function create() : void {
			for (var i:uint=0; i<_length; i++){
				addChild(new _navigationItemClass());
			}
		}	
			
		protected function onAddedToStage(event:Event):void{
			removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
			
			if(activeEvent)		addEventListener(activeEvent, onActiveEvent, true, 0, true);
			if(nonActiveEvent)	addEventListener(nonActiveEvent, onNonActiveEvent, true, 0, true);
			if(selectedEvent)	addEventListener(selectedEvent, onSelectedEvent, true, 0, true);
			
			if(_length && _navigationItemClass){
				create();
			}
		}
		
		protected function onSelectedEvent(event:Event):void{
			try{
				if(event.target == this) return;
				else{
					selectedIndex = getChildIndex(event.target as DisplayObject);
				}
			}
			catch(e:Error){}
		}
		
		protected function onActiveEvent(event:Event):void{
			try{
				activeIndex = getChildIndex(event.target as DisplayObject);
			}
			catch(e:Error){}
		}
		
		protected function onNonActiveEvent(event:Event):void{
			activeIndex = -1;
		}
		
		
	}
}
